package org.x.user.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson2.JSONObject;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.validation.constraints.NotEmpty;
import org.mindrot.jbcrypt.BCrypt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.x.common.config.BusinessException;
import org.x.common.pojo.SysUser;
import org.x.common.utils.SmsCache;
import org.x.user.dto.*;
import org.x.user.entity.*;
import org.x.user.mapper.*;
import org.x.user.service.ISysDeptService;
import org.x.user.service.SysUserService;
import org.x.user.vo.LoginVO;
import org.x.user.vo.SysUserVO;
import org.x.user.vo.UserAclVO;
import org.x.user.vo.UserInfoVO;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class SysUserSerivceImpl implements SysUserService {

    private static final Logger log = LoggerFactory.getLogger(SysUserSerivceImpl.class);
    @Autowired
    SysUserMapper sysUserMapper;

    @Autowired
    SysRoleUserMapper sysRoleUserMapper;

    @Autowired
    SysDeptMapper sysDeptMapper;

    @Autowired
    SysAclMapper sysAclMapper;

    @Autowired
    SysRoleAclMapper sysRoleAclMapper;

    @Autowired
    CodeMapper codeMapper;
    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    SysMenuMapper sysMenuMapper;

    @Override
    public Page<SysUserVO> pageList(UserQueryDTO userQueryDTO) {

        //判断userQuesyDTO中的值是否为null.不为null的才构建查询条件
        QueryWrapper queryWrapper = new QueryWrapper();
        if(!StringUtils.isEmpty(userQueryDTO.getUsername())){
            queryWrapper.like(SysUserEntity::getUsername,userQueryDTO.getUsername());
        }
        if(!StringUtils.isEmpty(userQueryDTO.getRealName())){
            queryWrapper.like(SysUserEntity::getRealName, userQueryDTO.getRealName());
        }
        if(userQueryDTO.getDeptId() != null){
            queryWrapper.eq(SysUserEntity::getDeptId, userQueryDTO.getDeptId());
        }
        if(userQueryDTO.getStatus() != null){
            queryWrapper.eq(SysUserEntity::getStatus, userQueryDTO.getStatus());
        }


        Page<SysUserEntity> paginate = sysUserMapper.paginate(userQueryDTO.getPage(), userQueryDTO.getSize(), queryWrapper);

        List<SysUserEntity> records = paginate.getRecords();
        Set<Long> userIds = records.stream().map(SysUserEntity::getId).collect(Collectors.toSet());

        QueryWrapper queryWrapper2 = new QueryWrapper();
        queryWrapper2.in(SysRoleUserEntity::getUserId, userIds);

        List<SysRoleUserEntity> sysRoleUserEntities = sysRoleUserMapper.selectListByQuery(queryWrapper2);
        /**
         *  map(userid,List<String>)
         */
        Map<Long,List<Long>> map = sysRoleUserEntities.stream()
                .collect(Collectors.groupingBy(SysRoleUserEntity::getUserId,Collectors.mapping(SysRoleUserEntity::getRoleId,Collectors.toList())));

        //paginate 转为  Page<SysUserVO>
        Page<SysUserVO> page = new Page<>();

        List<SysUserVO> list = new LinkedList<>();

        records.forEach(record -> {
            SysUserVO sysUserVO = new SysUserVO();
            BeanUtils.copyProperties(record, sysUserVO);

            Long userId = record.getId();
            List<Long> roleIds = map.get(userId);
            sysUserVO.setRoleIds(roleIds);
            list.add(sysUserVO);
        });

        page.setRecords(list);
        page.setTotalRow(paginate.getTotalRow());
        page.setTotalPage(paginate.getTotalPage());
        page.setPageNumber(paginate.getPageNumber());
        page.setPageSize(paginate.getPageSize());
        return page;
    }

    @Override
    @Transactional
    public int createUser(CreateUserDTO createUserDTO) {

        String password = createUserDTO.getPassword();
        /**
         * BCrypt加密
         */
        String encode = BCrypt.hashpw(password, BCrypt.gensalt());
        createUserDTO.setPassword(encode);

        SysUserEntity sysUserEntity = new SysUserEntity();
        BeanUtils.copyProperties(createUserDTO, sysUserEntity);

        // 设置用户类型（枚举转字符串）
        if (createUserDTO.getUserType() != null) {
            sysUserEntity.setUserType(createUserDTO.getUserType().getCode());
        }

        sysUserEntity.setStatus(false);
        sysUserEntity.setIsDelete(false);
        //@TODO
        sysUserEntity.setCreatedBy("admin");
        sysUserEntity.setCreatedTime(new Date());

        sysUserMapper.insertSelective(sysUserEntity);

        List<SysRoleUserEntity> list = new LinkedList<>();

        for (Long roleId : createUserDTO.getRoleIds()) {
            SysRoleUserEntity sysRoleUserEntity = new SysRoleUserEntity();
            sysRoleUserEntity.setUserId(sysUserEntity.getId());
            sysRoleUserEntity.setRoleId(roleId);
            list.add(sysRoleUserEntity);
        }

        return sysRoleUserMapper.insertBatch(list);
    }

    @Override
    public LoginVO login(LoginDTO loginDTO) {

        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("username", loginDTO.getUsername());

        String encode = BCrypt.hashpw(loginDTO.getPassword(), BCrypt.gensalt());

        SysUserEntity sysUserEntity = sysUserMapper.selectOneByQuery(wrapper);

        if(sysUserEntity == null) {
            throw new BusinessException("用户名不存在");
        }

        if(!BCrypt.checkpw(loginDTO.getPassword(), sysUserEntity.getPassword())) {
            throw new BusinessException("密码错误");
        }

        if(!sysUserEntity.getStatus()){
            throw new BusinessException("用户已禁用");
        }

        if(sysUserEntity.getIsDelete()){
            throw new BusinessException("用户已删除");
        }

        SysUser user = new SysUser();
        user.setUsername(sysUserEntity.getUsername());
        user.setUserType(sysUserEntity.getUserType());
        user.setUserId(sysUserEntity.getId());

        StpUtil.login(sysUserEntity.getId());
        StpUtil.getSession().set("user", user);


        LoginVO loginVO = new LoginVO();
        loginVO.setUserEntity(sysUserEntity);
        loginVO.setToken(StpUtil.getTokenValue());

        return loginVO;
    }

    @Override
    public int updateUser(UpdateUserDTO updateUserDTO) {

        SysUserEntity sysUserEntity = sysUserMapper.selectOneById(updateUserDTO.getUserId());

        if (sysUserEntity == null) {
            throw new BusinessException("当前用户ID不存在");
        }

        //校验部门的有效性 @TODO
        BeanUtils.copyProperties(updateUserDTO, sysUserEntity);

        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq(SysUserEntity::getId, updateUserDTO.getUserId());

        sysUserMapper.updateByQuery(sysUserEntity, wrapper);

        //更新角色关联

        //删除旧的角色关联

        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(SysRoleUserEntity::getUserId, updateUserDTO.getUserId());
        sysRoleUserMapper.deleteByQuery(queryWrapper);

        List<SysRoleUserEntity> list = new LinkedList<>();

       Long[] roleIds = updateUserDTO.getRoleIds();
       for(Long roleId : roleIds) {
           SysRoleUserEntity sysRoleUserEntity = new SysRoleUserEntity();
           sysRoleUserEntity.setUserId(updateUserDTO.getUserId());
           sysRoleUserEntity.setRoleId(roleId);
           list.add(sysRoleUserEntity);
       }

       return sysRoleUserMapper.insertBatch(list);

    }

    @Override
    public UserInfoVO getUserAuthInfo() {
        UserInfoVO userInfoVO = new UserInfoVO();

        SysUserEntity sysUserEntity = sysUserMapper.selectOneById(StpUtil.getLoginIdAsLong());

        if(sysUserEntity == null) {
            throw new BusinessException("当前用户不存在");
        }

        userInfoVO.setUsername(sysUserEntity.getUsername());
        userInfoVO.setUserId(sysUserEntity.getId());
        userInfoVO.setRealName(sysUserEntity.getRealName());
        userInfoVO.setDeptId(sysUserEntity.getDeptId());

        //---------------------------

        SysDeptEntity sysDeptEntity = sysDeptMapper.selectOneById(sysUserEntity.getDeptId());
        if(sysDeptEntity != null) {
            userInfoVO.setDeptName(sysDeptEntity.getName());
        }

        /**
         * select * from sys_role_user su
         * left  join sys_role_acl rc on su.role_id = rc.role_id
         * left join sys_acl sa on  rc.acl_id = sa.id
         * where su.user_id = '1'
         *
         */
        //查权限
        List<CodeDTO> code = codeMapper.getCode();
        List<String>  premis = code.stream().map(CodeDTO::getCode).collect(Collectors.toList());
        userInfoVO.setPermissions(premis);

        //查角色
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(SysRoleUserEntity::getUserId, StpUtil.getLoginIdAsLong());

        List<SysRoleUserEntity> sysRoleUserEntities = sysRoleUserMapper.selectListByQuery(queryWrapper);
        List<Long> roleIds = sysRoleUserEntities.stream().map(SysRoleUserEntity::getRoleId).collect(Collectors.toList());

        List<SysRoleEntity> sysRoleEntities = sysRoleMapper.selectListByIds(roleIds);
        List<String> roleNames = sysRoleEntities.stream().map(SysRoleEntity::getCode).collect(Collectors.toList());
        userInfoVO.setRoles(roleNames);

        //查菜单
        Set<Long> aclSet = code.stream().map(CodeDTO::getAclId).collect(Collectors.toSet());

        QueryWrapper aclQueryWrapper = new QueryWrapper();
        aclQueryWrapper.in(SysMenuEntity::getAclId, aclSet)
                .or("acl_id is null");
        List<SysMenuEntity> sysMenuEntities = sysMenuMapper.selectListByQuery(aclQueryWrapper);

        //需要将 sysMenuEntities 转为树形结构的menuTreeVOS

        List<UserInfoVO.MenuTreeVO> menuTreeVOS = this.buildTree(sysMenuEntities);
        userInfoVO.setMenuTree(menuTreeVOS);

        return userInfoVO;

    }


    public List<UserInfoVO.MenuTreeVO> buildTree(List<SysMenuEntity> menus) {
        // 1. 获取所有根节点（parentId为0或null的菜单）
        List<UserInfoVO.MenuTreeVO> roots = menus.stream()
                .filter(menu -> menu.getParentId() == null || 0 == menu.getParentId())
                .map(this::convertToVO)
                .collect(Collectors.toList());

        // 2. 递归构建子节点
        roots.forEach(root -> findChildren(root, menus));

        return roots;
    }

    private void findChildren(UserInfoVO.MenuTreeVO parent, List<SysMenuEntity> allMenus) {
        List<UserInfoVO.MenuTreeVO> children = allMenus.stream()
                .filter(menu -> parent.getId().equals(menu.getParentId()))
                .map(this::convertToVO)
                .collect(Collectors.toList());

        parent.setChildren(children);
        children.forEach(child -> findChildren(child, allMenus)); // 递归处理子节点
    }

    //转换为VO
    private UserInfoVO.MenuTreeVO convertToVO(SysMenuEntity entity) {
        UserInfoVO.MenuTreeVO vo = new UserInfoVO.MenuTreeVO();
        vo.setId(entity.getId());
        vo.setName(entity.getName());
        vo.setPath(entity.getPath());
        vo.setIcon(entity.getIcon());
        vo.setComponent(entity.getPath());

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("title", vo.getName());
        jsonObject.put("icon",vo.getIcon());
        jsonObject.put("hidden",entity.getHidden());
        vo.setMeta(jsonObject);

        // 其他字段拷贝...
        return vo;
    }


    //删除用户
    @Override
    public int deleteUser(DeleteUserDTO deleteUserDTO) {
        SysUserEntity sysUserEntity = sysUserMapper.selectOneById(deleteUserDTO.getUserId());
        if (sysUserEntity == null){
            throw new BusinessException("用户不存在") ;
        }
        sysUserEntity.setIsDelete(true);
        return sysUserMapper.delete(sysUserEntity);
    }





    @Override
    public UserProfileDTO getUserProfile() {
        // 获取当前登录用户的ID
        Long userId = StpUtil.getLoginIdAsLong();

        // 查询用户基本信息
        SysUserEntity sysUserEntity = sysUserMapper.selectOneById(userId);
        if (sysUserEntity == null) {
            throw new BusinessException("当前用户不存在");
        }

        // 查询部门信息
        SysDeptEntity sysDeptEntity = sysDeptMapper.selectOneById(sysUserEntity.getDeptId());

        // 构建UserProfileDto对象
        UserProfileDTO userProfileDto = new UserProfileDTO();
        userProfileDto.setUserId(sysUserEntity.getId());
        userProfileDto.setName(sysUserEntity.getUsername());
        userProfileDto.setAvatar(sysUserEntity.getAvatar());
        userProfileDto.setMobile(sysUserEntity.getMobile());
        userProfileDto.setEmail(sysUserEntity.getEmail());
        userProfileDto.setUserType(sysUserEntity.getUserType());
        userProfileDto.setAuthStatus(sysUserEntity.getAuthStatus());

        // 设置认证信息
        AuthInfoDTO authInfoDto = new AuthInfoDTO();
        authInfoDto.setRealName(sysUserEntity.getRealName());
        authInfoDto.setIdCard(sysUserEntity.getIdCard());
        userProfileDto.setAuthInfo(authInfoDto);

        // 设置部门名称
        if (sysDeptEntity != null) {
            userProfileDto.setDeptName(sysDeptEntity.getName());
        }

        return userProfileDto;
    }






    @Override
    public void updateUserProfile(UpdateProfileDTO updateProfileDTO) {
        // 获取当前登录用户的ID
        Long userId = StpUtil.getLoginIdAsLong();

        // 查询用户是否存在
        SysUserEntity sysUserEntity = sysUserMapper.selectOneById(userId);
        if (sysUserEntity == null) {
            throw new BusinessException("当前用户不存在");
        }

        // 更新用户信息
        sysUserEntity.setUsername(updateProfileDTO.getName());
        sysUserEntity.setAvatar(updateProfileDTO.getAvatar());
        sysUserEntity.setEmail(updateProfileDTO.getEmail());
        sysUserEntity.setMobile(updateProfileDTO.getMobile());

        // 构建更新条件
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(SysUserEntity::getId, userId);

        // 执行更新
        sysUserMapper.updateByQuery(sysUserEntity, queryWrapper);
    }




    @Override
    public void updatePassword(UpdatePasswordDTO updatePasswordDTO) {
        // 获取当前登录用户的ID
        Long userId = StpUtil.getLoginIdAsLong();

        // 查询用户是否存在
        SysUserEntity sysUserEntity = sysUserMapper.selectOneById(userId);
        if (sysUserEntity == null) {
            throw new BusinessException("当前用户不存在");
        }

        // 验证旧密码是否正确
        if (!BCrypt.checkpw(updatePasswordDTO.getOldPassword(), sysUserEntity.getPassword())) {
            throw new BusinessException("旧密码错误");
        }

        // 加密新密码
        String encodedNewPassword = BCrypt.hashpw(updatePasswordDTO.getNewPassword(), BCrypt.gensalt());

        // 更新密码
        sysUserEntity.setPassword(encodedNewPassword);

        // 构建更新条件
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(SysUserEntity::getId, userId);

        // 执行更新
        sysUserMapper.updateByQuery(sysUserEntity, queryWrapper);
    }





    @Override
    public void updatePhone(UpdatePhoneDTO updatePhoneDTO) {
        // 获取当前登录用户的ID
        Long userId = StpUtil.getLoginIdAsLong();

        // 查询用户是否存在
        SysUserEntity sysUserEntity = sysUserMapper.selectOneById(userId);
        if (sysUserEntity == null) {
            throw new BusinessException("当前用户不存在");
        }

        // 验证短信验证码是否正确（写死验证码为 "123456"）
        if (!"123456".equals(updatePhoneDTO.getSmsCode())) {
            throw new BusinessException("短信验证码错误");
        }

        // 更新手机号
        sysUserEntity.setMobile(updatePhoneDTO.getNewPhone());

        // 构建更新条件
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(SysUserEntity::getId, userId);

        // 执行更新
        sysUserMapper.updateByQuery(sysUserEntity, queryWrapper);
    }





    @Override
    public void submitAuth(AuthSubmitDTO authSubmitDTO) {
        // 获取当前登录用户的ID
        Long userId = StpUtil.getLoginIdAsLong();

        // 查询用户是否存在
        SysUserEntity sysUserEntity = sysUserMapper.selectOneById(userId);
        if (sysUserEntity == null) {
            throw new BusinessException("当前用户不存在");
        }
        // 校验是否已认证
        if ("VERIFIED".equals(sysUserEntity.getAuthStatus())) {
            throw new BusinessException("已认证，不可修改");
        }
        // 校验身份证号格式（示例：简单正则校验）
        if (!isValidIdCard(authSubmitDTO.getIdCard())) {
            throw new BusinessException("身份证号格式不正确");
        }

        // 更新用户实名认证信息
        sysUserEntity.setRealName(authSubmitDTO.getRealName());
        sysUserEntity.setIdCard(authSubmitDTO.getIdCard());
        sysUserEntity.setIdCardFront(authSubmitDTO.getIdCardFront());
        sysUserEntity.setIdCardBack(authSubmitDTO.getIdCardBack());
        sysUserEntity.setAuthStatus("PENDING"); // 设置为待审核状态

        // 构建更新条件
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(SysUserEntity::getId, userId);

        // 执行更新
        sysUserMapper.updateByQuery(sysUserEntity, queryWrapper);
    }

    /**
     * 校验身份证号格式（示例：中国大陆身份证号）
     *
     * @param idCard 身份证号
     * @return 是否有效
     */
    private boolean isValidIdCard(String idCard) {
        String regex = "^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9Xx]$";
        return idCard.matches(regex);
    }


    // 在 SysUserSerivceImpl.java 中添加
    @Override
    public void updateUserPassword(UpdateUserPasswordDTO updatePasswordDTO) {
        // 获取用户信息
        SysUserEntity sysUserEntity = sysUserMapper.selectOneById(updatePasswordDTO.getUserId());
        if (sysUserEntity == null) {
            throw new BusinessException("当前用户不存在");
        }

        // 加密新密码
        String encodedNewPassword = BCrypt.hashpw(updatePasswordDTO.getPassword(), BCrypt.gensalt());

        // 更新密码
        sysUserEntity.setPassword(encodedNewPassword);

        // 构建更新条件
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(SysUserEntity::getId, updatePasswordDTO.getUserId());

        // 执行更新
        sysUserMapper.updateByQuery(sysUserEntity, queryWrapper);
    }




    // 在 SysUserSerivceImpl.java 中添加
    @Override
    public String uploadAvatar(MultipartFile file) {
        // 获取当前登录用户的ID
        Long userId = StpUtil.getLoginIdAsLong();

        // 查询用户是否存在
        SysUserEntity sysUserEntity = sysUserMapper.selectOneById(userId);
        if (sysUserEntity == null) {
            throw new BusinessException("当前用户不存在");
        }

        // 检查文件是否为空
        if (file.isEmpty()) {
            throw new BusinessException("上传文件不能为空");
        }

        // 检查文件类型
        String contentType = file.getContentType();
        if (!"image/jpeg".equals(contentType) && !"image/png".equals(contentType)) {
            throw new BusinessException("只支持JPG/PNG格式的图片");
        }

        // 检查文件大小（限制为2MB）
        if (file.getSize() > 2 * 1024 * 1024) {
            throw new BusinessException("图片大小不能超过2MB");
        }

        try {
            // 生成文件名（使用用户ID和时间戳）
            String originalFilename = file.getOriginalFilename();
            String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String newFilename = userId + "_" + System.currentTimeMillis() + fileExtension;

            // 设置文件保存路径（这里以项目目录下的uploads文件夹为例）
            String uploadDir = System.getProperty("user.dir") + "/uploads/avatar/";
            File uploadPath = new File(uploadDir);
            if (!uploadPath.exists()) {
                uploadPath.mkdirs();
            }

            // 保存文件
            String filePath = uploadDir + newFilename;
            file.transferTo(new File(filePath));

            // 构建访问URL（根据实际部署情况调整路径）
            String avatarUrl = "/uploads/avatar/" + newFilename;

            // 更新用户头像URL
            sysUserEntity.setAvatar(avatarUrl);
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq(SysUserEntity::getId, userId);
            sysUserMapper.updateByQuery(sysUserEntity, queryWrapper);

            return avatarUrl;
        } catch (IOException e) {
            log.error("头像上传失败", e);
            throw new BusinessException("头像上传失败");
        }
    }

    @Override
    public UserAclVO userPermissions(Long id) {
        UserAclVO vo = new UserAclVO();

        SysUserEntity sysUserEntity = sysUserMapper.selectOneById(id);

        if(sysUserEntity == null) {
            throw new BusinessException("当前用户不存在");
        }

        vo.setUserId(sysUserEntity.getId());

        //查权限
        List<CodeDTO> code = codeMapper.getCode();
        List<String>  premis = code.stream().map(CodeDTO::getCode).collect(Collectors.toList());
        vo.setPermissions(premis);

        //查角色
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(SysRoleUserEntity::getUserId, StpUtil.getLoginIdAsLong());

        List<SysRoleUserEntity> sysRoleUserEntities = sysRoleUserMapper.selectListByQuery(queryWrapper);
        List<Long> roleIds = sysRoleUserEntities.stream().map(SysRoleUserEntity::getRoleId).collect(Collectors.toList());

        List<SysRoleEntity> sysRoleEntities = sysRoleMapper.selectListByIds(roleIds);
        List<String> roleNames = sysRoleEntities.stream().map(SysRoleEntity::getCode).collect(Collectors.toList());
        vo.setRoles(roleNames);

        //查菜单
        Set<Long> aclSet = code.stream().map(CodeDTO::getAclId).collect(Collectors.toSet());

        QueryWrapper aclQueryWrapper = new QueryWrapper();
        aclQueryWrapper.in(SysMenuEntity::getAclId, aclSet)
                .or("acl_id is null");
        List<SysMenuEntity> sysMenuEntities = sysMenuMapper.selectListByQuery(aclQueryWrapper);

        //需要将 sysMenuEntities 转为树形结构的menuTreeVOS

        List<UserAclVO.MenuTreeVO> menuTreeVOS = this.buildTreeForAcl(sysMenuEntities);
        vo.setMenuTree(menuTreeVOS);

        return vo;

    }

    public List<UserAclVO.MenuTreeVO> buildTreeForAcl(List<SysMenuEntity> menus) {
    List<UserAclVO.MenuTreeVO> roots = menus.stream()
            .filter(menu -> menu.getParentId() == null || 0 == menu.getParentId())
            .map(this::convertToAclVO)
            .collect(Collectors.toList());

    roots.forEach(root -> findChildrenForAcl(root, menus));
    return roots;
}

    private void findChildrenForAcl(UserAclVO.MenuTreeVO parent, List<SysMenuEntity> allMenus) {
        List<UserAclVO.MenuTreeVO> children = allMenus.stream()
                .filter(menu -> parent.getId().equals(menu.getParentId()))
                .map(this::convertToAclVO)
                .collect(Collectors.toList());

        parent.setChildren(children);
        children.forEach(child -> findChildrenForAcl(child, allMenus));
    }

    private UserAclVO.MenuTreeVO convertToAclVO(SysMenuEntity entity) {
        UserAclVO.MenuTreeVO vo = new UserAclVO.MenuTreeVO();
        vo.setId(entity.getId());
        vo.setName(entity.getName());
        vo.setPath(entity.getPath());
        vo.setIcon(entity.getIcon());
        vo.setComponent(entity.getPath());

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("title", vo.getName());
        jsonObject.put("icon", vo.getIcon());
        jsonObject.put("hidden", entity.getHidden());
        vo.setMeta(jsonObject);

        return vo;
    }

}
